{-
This is where the open source liecense will go once I decide which one to use
-}
module HibTeX.Parser where

import Text.ParserCombinators.Parsec


{-
Need to change all code to ignore case of keys.
Author is acceptable, so is @BOOK, @Book, AUThor, etc.
-}
type Name = String


type Value = String


{- This is the storage for the key-value pair.
e.g. author = "Nathan M. Wiegand" would translate to
        BibValue "author" "Nathan M. Wiegand"
-}

data BibValue = BibValue Name Value
      deriving  (Show, Eq, Ord)

data BibTeXType = BComment String
        | BEntity String String [BibValue]
      deriving (Show, Eq, Ord)




hibTeXParse fn str = parse parseFile fn str

parseFile :: GenParser Char st [BibTeXType]
parseFile = many parseBibTeXType

parseBibTeXType :: GenParser Char st BibTeXType
parseBibTeXType = parseTopLevelEntity
        <|> parseTopLevelComment


parseTopLevelComment :: GenParser Char st BibTeXType
parseTopLevelComment = many1 (noneOf "@") >>= return.BComment

-- Starts with '@'
parseTopLevelEntity :: GenParser Char st BibTeXType 
parseTopLevelEntity = do
        char '@'
        name <- word
        char '{'
	simpleSpace
        id <- word
        char ','
	simpleSpace
        body <- parseBody
        char '}'
        return (BEntity name id body)

{-
@comment {commentstuff} is a comment that is allowable in
the body of an entity.  Need to take this into accout.        
-}
parseBody :: GenParser Char st [BibValue]
parseBody =  parseKeyValue `sepEndBy1` ((char ',')>>simpleSpace)

{-
Right now, all key-value pairs must end with a comma.  The last
one can be ommited.
-}
parseKeyValue :: GenParser Char st BibValue
parseKeyValue = do
        simpleSpace
        name <- word
        char '='
        simpleSpace
        value <- parseValue
        simpleSpace
        return (BibValue name value)


{- 
parseValue needs a lot of work.  Right now it only parses things like this:
        key = {this is the contents of the variable key}
it does not handle nested brackets or normal quotes or bare numbers. 
-}

parseValue :: GenParser Char st String
parseValue = do
        char '{'
        value <- many (noneOf "}")
        char '}'
        return value


simpleSpace = skipMany (oneOf " \t\n\r")
     
word = 	do { x <-many1 letter; simpleSpace; return x }

